#ifndef ODBC_DETAILS_NUMBER_BUFFER_BASE_HPP
#define ODBC_DETAILS_NUMBER_BUFFER_BASE_HPP

#include "odbc/details/buffer_base.hpp"
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>

namespace odbc { namespace details
{

/// \ingroup odbcpp
/// \brief It provides the functionality common to the buffers mapping arithmetic types.
/// \param T the numeric type mapped to the buffer.
/// \param OdbcTID the identifier of the ODBC type corresponding to the numeric type to be mapped to the buffer. 
///		See odbc::odbc_types
/// \param SqlTID the identifier of the SQL type corresponding to the numeric type to be mapped to the buffer.
///		See odbc::sql_types
/// \pre the type T is either integral or floating point, built-in type.
template< class T, odbc_types::type_enum OdbcTID, sql_types::type_enum SqlTID>
class number_buffer_base: public buffer_base< OdbcTID, SqlTID>
{
	BOOST_STATIC_ASSERT( boost::is_integral<T>::value || boost::is_floating_point<T>::value);

	typedef buffer_base< OdbcTID, SqlTID> MyBaseT_;

public:
	typedef T value_type;
	typedef T buffer_type;
	typedef typename MyBaseT_::size_type size_type;

public:
	/// \brief It initializes the buffer with the given initial value.
	number_buffer_base( const T& initial_value)
		: MyBaseT_( sizeof( buffer_type))
		, buffer_( initial_value)
	{
	}

	/// \brief It initializes the buffer with 0.
	number_buffer_base()
		: buffer_( 0)
	{
	}

	///	\brief It sets the value in the buffer.
	/// \param value the value to be copied in the buffer.
	void set_value( const value_type& value)
	{
		buffer_ = value;
		this->set_length_indicator( sizeof( value));
	}

	/// \brief It gets the value from the buffer.
	const value_type& value() const { return buffer_; }

	/// \brief It gets the memory address of the buffer.
	/// \details
	///		The buffer address is requested by ODBC API functions and it is not intended for direct use.
	/// \{
	void* buffer_addr() { return static_cast< void*>( &buffer_); }
	const void* buffer_addr() const { return static_cast<const void*>( &buffer_); }
	/// \}

	/// \brief It gets the size of the buffer.
	size_type size() const { return sizeof( buffer_); }

private:
	value_type buffer_;
};


}} //  namespace details // namespace odbc

#endif // ODBC_DETAILS_NUMBER_BUFFER_BASE_HPP
